package com.xkdx.guangguang.util;

import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.net.HttpURLConnection;
import java.net.MalformedURLException;
import java.net.URL;
import java.util.HashMap;
import java.util.Map;
import java.util.WeakHashMap;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;

import android.content.Context;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.drawable.Drawable;
import android.os.Handler;
import android.os.Message;
import android.util.Log;
import android.widget.ImageView;

import com.xkdx.guangguang.module.statics.IConstants;

public class AsyncImageLoader {
	private static String TAG = "AsyncImageLoader";

	private static AsyncImageLoader instance = null;
	private WeakHashMap<String, Drawable> imageCache;
	static Context context;
	private ExecutorService executorService;
	private boolean allowLoad = true; // 是否允许加载图片
	private Map<String, ImageView> taskMap;

	public AsyncImageLoader(Context context) {
		imageCache = new WeakHashMap<String, Drawable>();

		int cpuNums = Runtime.getRuntime().availableProcessors();
		// 根据系统资源情况灵活定义线程池大小
		this.executorService = Executors.newFixedThreadPool(cpuNums + 1);
		this.taskMap = new HashMap<String, ImageView>();
		this.context = context;
	}

	public static AsyncImageLoader getInstance() {
		if (instance == null)
			instance = new AsyncImageLoader(context);
		return instance;
	}

	public Drawable loadDrawable(final String imageUrl, final String time, final ImageCallback imageCallback) {

		if (imageCache.get(imageUrl) != null) {
			// Log.i("AsyncImageLoader", "从软缓存取");
			return imageCache.get(imageUrl);
		} else {
			// Log.i("AsyncImageLoader", "为空");

		}

		final Handler handler = new Handler() {
			public void handleMessage(Message message) {
				imageCallback.imageLoaded((Drawable) message.obj, imageUrl);
			}
		};

		new Thread() {
			@Override
			public void run() {

				Drawable drawable = loadImageFromUrl(imageUrl);
				if (drawable != null) {
					// Log.i("AsyncImageLoader", "不为空");
				}

				imageCache.put(imageUrl, drawable);
				Message message = handler.obtainMessage(0, drawable);
				handler.sendMessage(message);
			}
		}.start();

		return null;
	}

	public Drawable loadeDrawable(final String imageUrl, final ImageCallback imageCallback) {
		if (imageCache.get(imageUrl) != null) {

			return imageCache.get(imageUrl);
		} else {
			// Log.i("AsyncImageLoader", "为空");
		}

		final Handler handler = new Handler() {
			public void handleMessage(Message message) {
				imageCallback.imageLoaded((Drawable) message.obj, imageUrl);
			}
		};
		new Thread() {
			@Override
			public void run() {
				Drawable drawable = loadImageFromUrl(imageUrl);
				if (drawable != null) {
					// Log.i("AsyncImageLoader", "不为空");
				}

				imageCache.put(imageUrl, drawable);
				Message message = handler.obtainMessage(0, drawable);
				handler.sendMessage(message);
			}
		}.start();
		return null;
	}

	public Drawable loadImageFromUrl(String url) {
		URL m;
		Drawable d = null;
		InputStream i = null;
		try {
			m = new URL(url);
			i = m.openStream();
			d = Drawable.createFromStream(i, "src");
		} catch (Exception e) {
			e.printStackTrace();
		}

		return d;
	}

	public Bitmap loadPhotoImageFromUrl(String url) {
		URL m;
		Bitmap d = null;
		InputStream i = null;
		try {
			m = new URL(url);
			i = m.openStream();

			BitmapFactory.Options opts = new BitmapFactory.Options();
			opts.inSampleSize = 4;
			opts.inJustDecodeBounds = false;
			d = BitmapFactory.decodeStream(i, null, opts);
			opts.inSampleSize = IConstants.computeSampleSize(opts, -1, 800 * 800);
			// Log.i(TAG, "inSampleSize-->" + opts.inSampleSize);
			opts.inJustDecodeBounds = true;
			d = BitmapFactory.decodeStream(i, null, opts);
			// d = BitmapFactory.decodeStream(i);

		} catch (Exception e) {
			e.printStackTrace();
		}

		return d;
	}

	public Bitmap loadOrigeImageFromUrl(String url) {
		URL m;
		Bitmap d = null;
		InputStream i = null;
		try {
			m = new URL(url);
			i = m.openStream();
			BitmapFactory.Options opts = new BitmapFactory.Options();
			opts.inSampleSize = 4;
			opts.inJustDecodeBounds = true;
			d = BitmapFactory.decodeStream(i, null, opts);
			opts.inSampleSize = IConstants.computeSampleSize(opts, -1, 400 * 400);
			// Log.i(TAG, "inSampleSize-->" + opts.inSampleSize);
			opts.inJustDecodeBounds = false;
			d = BitmapFactory.decodeStream(i, null, opts);
			// d = BitmapFactory.decodeStream(i);

		} catch (MalformedURLException e1) {
			e1.printStackTrace();
		} catch (IOException e) {
			e.printStackTrace();
		}

		return d;
	}

	public interface ImageCallback {
		public void imageLoaded(Drawable imageDrawable, String imageUrl);
	}

	public Bitmap getBiggerBitmapFromURL(final String urlPath) {
		byte[] imageByte = getImageFromURL(urlPath.trim());

		Bitmap bitmap = null;
		if (imageByte != null) {

			// 以下是把图片转化为缩略图再加载
			BitmapFactory.Options options = new BitmapFactory.Options();
			// true,只是读图片大小，不申请bitmap内存
			options.inJustDecodeBounds = true;
			bitmap = BitmapFactory.decodeByteArray(imageByte, 0, imageByte.length, options);
			//System.out.println("width=" + options.outWidth + "; height=" + options.outHeight);

			int be = 1;
			options.inSampleSize = be;
			options.inJustDecodeBounds = false;
			try {
				bitmap = BitmapFactory.decodeByteArray(imageByte, 0, imageByte.length, options);
			} catch (OutOfMemoryError e) {
			}

		}
		return bitmap;
	}

	public byte[] getImageFromURL(String urlPath) {
		byte[] data = null;
		InputStream is = null;
		HttpURLConnection conn = null;
		try {
			URL url = new URL(urlPath);
			conn = (HttpURLConnection) url.openConnection();
			conn.setDoInput(true);
			conn.setRequestMethod("GET");
			conn.setConnectTimeout(5 * 1000);
			is = conn.getInputStream();
			if (conn.getResponseCode() == 200) {
				data = readInputStream(is);
			} else
				Log.v("", "net state" + conn.getResponseCode());

		} catch (MalformedURLException e) {
			e.printStackTrace();
		} catch (IOException e) {
			e.printStackTrace();
		} finally {
			conn.disconnect();
			try {
				if (is != null) {
					is.close();
				}

			} catch (IOException e) {
				e.printStackTrace();
			}
		}
		return data;
	}

	public byte[] readInputStream(InputStream is) {
		ByteArrayOutputStream baos = new ByteArrayOutputStream();
		byte[] buffer = new byte[1024];
		int length = -1;
		try {
			while ((length = is.read(buffer)) != -1) {
				baos.write(buffer, 0, length);
			}
			baos.flush();
		} catch (OutOfMemoryError e) {
			Log.v("", e.getMessage());
		} catch (IOException e) {
			e.printStackTrace();
		}

		byte[] data = null;
		try {
			// bm.compress(Bitmap.CompressFormat.PNG, 100, baos);
			data = baos.toByteArray();
		} catch (OutOfMemoryError e) {
			Log.v("", e.getMessage());
		}
		try {
			is.close();
			baos.close();
		} catch (IOException e) {
			e.printStackTrace();
		}
		return data;
	}

	public static int calculateInSampleSize(BitmapFactory.Options options, int reqWidth, int reqHeight) {
		// Raw height and width of image
		final int height = options.outHeight;
		final int width = options.outWidth;
		int inSampleSize = 1;

		if (height > reqHeight || width > reqWidth) {
			if (width > height) {
				inSampleSize = Math.round((float) height / (float) reqHeight);
			} else {
				inSampleSize = Math.round((float) width / (float) reqWidth);
			}

			// This offers some additional logic in case the image has a strange
			// aspect ratio. For example, a panorama may have a much larger
			// width than height. In these cases the total pixels might still
			// end up being too large to fit comfortably in memory, so we should
			// be more aggressive with sample down the image (=larger
			// inSampleSize).

			final float totalPixels = width * height;

			// Anything more than 2x the requested pixels we'll sample down
			// further.
			final float totalReqPixelsCap = reqWidth * reqHeight * 2;

			while (totalPixels / (inSampleSize * inSampleSize) > totalReqPixelsCap) {
				inSampleSize++;
			}
		}
		return inSampleSize;
	}
}
